parser grammar BParser;

options {
    output    = AST;
    superClass = AbstractBParser;
    tokenVocab = BLexer;
}

@header {
    package com.nts.bupna;
}

process : PROCESS^ 
            LEFT_PAR! 
                processParams
            RIGHT_PAR! 
            LEFT_CURLY! 
                processBody
            RIGHT_CURLY!
            ;
            
processParams : nameParam COMMA! PACKAGE EQ! qualifiedId ;

qualifiedId : ID_STRING | QID_STRING;

processBody : imports? vars receive activity reply? ;

imports : IMPORTS^ LEFT_CURLY! anImport (COMMA! anImport)* RIGHT_CURLY! ;

anImport : STATIC? (QID_STRING | QID_STAR_STRING);
                 
vars : VARS^ LEFT_CURLY! (var)+ RIGHT_CURLY! ;
       
var : VAR^ LEFT_PAR! varParams RIGHT_PAR!;

varParams : nameParam COMMA! typeParam (COMMA! INIT EQ! ID_STRING)?;  

receive : RECEIVE^ LEFT_PAR! varParam COMMA! nameParam RIGHT_PAR!;

invoke : INVOKE^ LEFT_PAR! invokeParams RIGHT_PAR!;

reply : REPLY^ LEFT_PAR! resultParam RIGHT_PAR!;

sequence : SEQUENCE^ LEFT_CURLY! activity+ RIGHT_CURLY!;

assign : ASSIGN^ LEFT_PAR! (from | expr) COMMA! TO EQ! qualifiedId RIGHT_PAR!;

from : FROM EQ! qualifiedId;

expr : EXPR EQ! STRING;

whileActivity : WHILE^ LEFT_PAR! condition RIGHT_PAR!   
                LEFT_CURLY!
                    activity
                RIGHT_CURLY!;

ifActivity  : IF^ LEFT_PAR! condition RIGHT_PAR! 
                LEFT_CURLY! 
                    activity
                    elseif*
                    elseSubActivity?
                RIGHT_CURLY!;

elseif : ELSEIF^ LEFT_PAR! condition RIGHT_PAR! 
                LEFT_CURLY! 
                    activity
                RIGHT_CURLY!;

throwActivity : THROW^ LEFT_PAR! ERROR EQ! ID_STRING RIGHT_PAR!;

elseSubActivity : ELSE^ LEFT_CURLY! activity RIGHT_CURLY!; 

activity : sequence | invoke | assign | ifActivity | whileActivity | throwActivity; 

invokeParams 
    : typeParam COMMA! 
      methodParam  
      (COMMA! varParam)? 
      ((COMMA! methodTypeParam) | (COMMA! serviceParam))?
      (COMMA! resultParam)?
;

resultParam : RESULT EQ! ID_STRING;

condition : CONDITION EQ! STRING;

methodParam : METHOD EQ! ID_STRING;

methodTypeParam : METHOD_TYPE EQ! ID_STRING;

typeParam : TYPE EQ! ID_STRING;

varParam :(VAR EQ! ID_STRING) | (VARS EQ! ID_LIST_STRING);

nameParam : NAME EQ! ID_STRING;

serviceParam : SERVICE EQ! ID_STRING;